home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / tarsrc Folder / window.c < prev   
Text File  |  1991-08-04  |  7KB  |  348 lines

  1. /*
  2.  * Macintosh Tar
  3.  *
  4.  * Written by Craig Ruff
  5.  *
  6.  * Window manipulation routines for display (and printer) listings of archives.
  7.  */
  8.  
  9. #include "tar.h"
  10. #include <Resources.h>
  11. #include <StdArg.h>
  12.  
  13. #define dispID    129        /* Display window ID (in resource file) */
  14. #define LEFTMAR    5
  15. #define TOPMAR    5
  16.  
  17. WindowPtr    dispWind;
  18. Boolean        windOpen = false;
  19. short        fontHeight;
  20. short        bottomMargin;
  21. short        bottomLine;
  22. short        topLine;
  23. short        curLine;
  24. short        wLines;
  25. short        wCurLine = 0;
  26. RgnHandle     update;
  27. TPPrPort    prPort;
  28. GrafPtr        savedPort;
  29.  
  30. /*
  31.  * WindInit - either open the window or printer port
  32.  *
  33.  *    Returns true if an error is found, false otherwise.
  34.  *
  35.  *    Separate routines for screen and printer are not really needed.
  36.  */
  37. Boolean
  38. WindInit() {
  39.     FontInfo    fInfo;
  40.     char        *routine = "\pWindInit";
  41.  
  42.     if (pref.doPrint) {
  43.         /*
  44.          * We are listing to the printer.
  45.          * Make sure we have opened the printer driver.
  46.          */
  47.         if (!pOpen && PrSetup())
  48.             return(true);
  49.  
  50.         /*
  51.          * Ask about this listings specifics.
  52.          */
  53.         if (PrJobDialog(prRecHdl) == false)
  54.             return(true);
  55.  
  56.         if (PrError() != noErr) {
  57.             OSAlert(routine, "\pPrJobDialog", nil, PrError());
  58.             return(true);
  59.         }
  60.  
  61.         /*
  62.          * Open the printer document (once per listing).
  63.          */
  64.         prPort = PrOpenDoc(prRecHdl, nil, nil);
  65.         if (PrError() != noErr) {
  66.             OSAlert(routine, "\pPrOpenDoc", nil, PrError());
  67.             return(true);
  68.         }
  69.  
  70.         /*
  71.          * Open the page (once per physical page).
  72.          */
  73.         PrOpenPage(prPort, nil);
  74.         if (PrError() != noErr) {
  75.             OSAlert(routine, "\pPrOpenPage", nil, PrError());
  76.             return(true);
  77.         }
  78.  
  79.         /*
  80.          * Use monaco 9 so our listing lines up properly.
  81.          * (Lazy)
  82.          */
  83.         GetPort(&savedPort);
  84.         SetPort(&prPort->gPort);
  85.         TextFont(monaco);
  86.         TextSize(9);
  87.  
  88.         /*
  89.          * Figure out how many lines fit on a page.
  90.          */
  91.         GetFontInfo(&fInfo);
  92.         fontHeight = fInfo.ascent + fInfo.descent + fInfo.leading;
  93.         MoveTo(LEFTMAR, curLine = fontHeight);
  94.         bottomLine = (((**prRecHdl).prInfo.rPage.bottom / fontHeight) - 1)
  95.                 * fontHeight;
  96.  
  97.         return(false);
  98.     }
  99.  
  100.     /*
  101.      * Listing to screen.
  102.      * Get a temporary region for scrolling bits.
  103.      * Get the window template from the resource file.
  104.      */
  105.     if ((update = NewRgn()) == nil) {
  106.         OSAlert(routine, "\pNewRgn", nil, MemError());
  107.         return(true);
  108.     }
  109.  
  110.     if ((dispWind = GetNewWindow(dispID, nil, (WindowPtr) -1)) == nil) {
  111.         OSAlert(routine, "\pGetNewWindow", nil, ResError());
  112.         return(true);
  113.     }
  114.  
  115.     /*
  116.      * Use monaco 9 so our listing lines up.
  117.      */
  118.     SetPort(dispWind);
  119.     TextFont(monaco);
  120.     TextSize(9);
  121.  
  122.     /*
  123.      * Figure out how many lines fit on a page, save this as margin info.
  124.      */
  125.     GetFontInfo(&fInfo);
  126.     fontHeight = fInfo.ascent + fInfo.descent + fInfo.leading;
  127.  
  128.     MoveTo(LEFTMAR, curLine = fontHeight);
  129.     topLine = curLine + fInfo.descent + fInfo.leading;
  130.     bottomLine = (wLines = dispWind->portRect.bottom / fontHeight) * fontHeight;
  131.     bottomMargin = bottomLine + fInfo.descent + fInfo.leading;
  132.  
  133.     wCurLine = 0;
  134.     windOpen = true;
  135.     return(false);
  136. }
  137.  
  138. /*
  139.  * WindEnd - clean up after a listing to screen or printer
  140.  */
  141. WindEnd(keyWait)
  142. Boolean    keyWait;
  143. {
  144.     if (pOpen) {
  145.         TPrStatus    prSt;
  146.         char        *routine = "\pWindEnd";
  147.         short        err;
  148.  
  149.         /*
  150.          * Printing, close page and document.
  151.          */
  152.         PrClosePage(prPort);
  153.         if ((err = PrError()) != noErr) {
  154.             if (err != iPrAbort)
  155.                 OSAlert(routine, "\pPrClosePage", nil, PrError());
  156.             goto done;
  157.         }
  158.  
  159.         PrCloseDoc(prPort);
  160.         if ((err = PrError()) != noErr) {
  161.             if (err != iPrAbort)
  162.                 OSAlert(routine, "\pPrCloseDoc", nil, PrError());
  163.             goto done;
  164.         }
  165.  
  166.         /*
  167.          * If the printing involved spooling, spool it now.
  168.          */
  169.         if ((**prRecHdl).prJob.bJDocLoop == bSpoolLoop) 
  170.             PrPicFile(prRecHdl, nil, nil, nil, &prSt);
  171.  
  172.     done:    SetPort(savedPort);
  173.         pOpen = false;
  174.         return;
  175.     }
  176.  
  177.     /*
  178.      * Listing to screen.  See if we should wait for a key press to continue.
  179.      */
  180.     if (keyWait) {
  181.         EventRecord    e;
  182.         Boolean        oldAutoPage = pref.autoPage;
  183.  
  184.         pref.autoPage = false;    /* So we don't get two messages */
  185.         if (!pref.doPrint)
  186.             WPrintf("Press any key to continue");
  187.  
  188.         do {
  189.             SystemTask();
  190.             if (GetNextEvent(keyDownMask, &e) == false)
  191.                 e.what = nullEvent;
  192.         } while (e.what != keyDown);
  193.  
  194.         pref.autoPage = oldAutoPage;
  195.     }
  196.  
  197.     DisposeWindow(dispWind);
  198.     DisposeRgn(update);
  199.     windOpen = false;
  200. }
  201.  
  202. /*
  203.  * WPrintf - printf to the screen or printer
  204.  *
  205.  *     Used like you'd expect, but does NOT handle paper motion
  206.  *    characters like newline, etc.
  207.  */
  208. WPrintf(char *fmt, ...)
  209. {
  210.     Rect        r;
  211.     char        buf[256];
  212.     EventRecord    e;
  213.     char        *routine = "\pWPrintf";
  214.     short        err;
  215.     va_list        ap;
  216.  
  217.     if (!windOpen && !pOpen)
  218.         return;
  219.  
  220.     va_start(ap, fmt);
  221.     vsprintf(buf, fmt, ap);
  222.     va_end(ap);
  223.     if (strlen(buf) >= sizeof(buf))
  224.         StkErrAlert();        /* Sanity check, stack overrun */
  225.  
  226.     if (pref.doPrint) {
  227.         /*
  228.          * Printing.
  229.          */
  230.         if (curLine > bottomLine) {
  231.             /*
  232.              * At end of page, start a new one.
  233.              */
  234.             PrClosePage(prPort);
  235.             if ((err = PrError()) != noErr) {
  236.                 if (err != iPrAbort)
  237.                     OSAlert(routine, "\pPrClosePage", nil,
  238.                             PrError());
  239.                 return;
  240.             }
  241.  
  242.             PrOpenPage(prPort, nil);
  243.             if (PrError() != noErr) {
  244.                 if (err != iPrAbort)
  245.                     OSAlert(routine, "\pPrClosePage", nil,
  246.                             PrError());
  247.                 return;
  248.             }
  249.  
  250.             /*
  251.              * Yes, we really must reset the font.
  252.              */
  253.             MoveTo(LEFTMAR, curLine = fontHeight);
  254.             TextFace(underline);
  255.             DrawText(header, 0, strlen(header));
  256.             TextFace(0);
  257.             MoveTo(LEFTMAR, curLine += fontHeight);
  258.         }
  259.  
  260.         DrawText(buf, 0, strlen(buf));
  261.         MoveTo(LEFTMAR, curLine += fontHeight);
  262.         return;
  263.     }
  264.  
  265.     /*
  266.      * On screen.
  267.      */
  268.     SetPort(dispWind);
  269.     if (curLine > bottomLine) {
  270.         /*
  271.          * At end of screen, scroll up.
  272.          */
  273.         SetRect(&r, dispWind->portRect.left, topLine,
  274.                 dispWind->portRect.right, bottomMargin);
  275.         ScrollRect(&r, 0, -fontHeight, update);
  276.         SetEmptyRgn(update);
  277.         MoveTo(LEFTMAR, curLine = bottomLine);
  278.     }
  279.  
  280.     if (pref.autoPage && (++wCurLine == wLines)) {
  281.         /*
  282.          * At end of screen, wait for key press.
  283.          */
  284.         wCurLine = 0;
  285.         DrawText("Press any key to continue", 0, 25);
  286.         do {
  287.             SystemTask();
  288.             if (GetNextEvent(keyDownMask, &e) == false)
  289.                 e.what = nullEvent;
  290.         } while (e.what != keyDown);
  291.  
  292.         SetRect(&r, dispWind->portRect.left, bottomMargin - fontHeight,
  293.                 dispWind->portRect.right, bottomMargin);
  294.         EraseRect(&r);
  295.         MoveTo(LEFTMAR, curLine);
  296.  
  297.     } else {
  298.         /*
  299.          * No auto page, only stop if command S is pressed.
  300.          */
  301.         if (GetNextEvent(keyDownMask, &e)) {
  302.             if (((e.message & charCodeMask & ~0x20) == 'S')
  303.                         && (e.modifiers & cmdKey)) {
  304.                 do {
  305.                     /*
  306.                      * Start again after command Q.
  307.                      */
  308.                     SystemTask();
  309.                     if (GetNextEvent(keyDownMask, &e) == false)
  310.                         e.message = 0;
  311.  
  312.                     e.message &= charCodeMask & ~0x20;
  313.                 } while (e.message != 'Q');
  314.             }
  315.         }
  316.     }
  317.  
  318.     DrawText(buf, 0, strlen(buf));
  319.     MoveTo(LEFTMAR, curLine += fontHeight);
  320. }
  321.  
  322. /*
  323.  * PrSetup - make sure the printer driver has been opened.
  324.  *
  325.  *    Returns true if an error is found, false otherwise.
  326.  */
  327. Boolean
  328. PrSetup() {
  329.     char    *routine = "\pPrSetup";
  330.  
  331.     if (!pOpen) {
  332.         PrOpen();
  333.         if (PrError() != noErr) {
  334.             OSAlert(routine, "\pPrOpen", nil, PrError());
  335.             return(true);
  336.         }
  337.  
  338.         pOpen = true;
  339.         PrintDefault(prRecHdl);
  340.         if (PrError() != noErr) {
  341.             OSAlert(routine, "\pPrintDefault", nil, PrError());
  342.             return(true);
  343.         }
  344.     }
  345.  
  346.     return(false);
  347. }
  348.